package com.xixilala.video.practices

import android.media.MediaCodec
import android.media.MediaExtractor
import android.media.MediaFormat
import android.media.MediaMuxer
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import com.xixilala.video.App
import com.xixilala.video.base.BaseFragment
import com.xixilala.video.databinding.FragmentPractice4Binding
import com.xixilala.video.util.ExecutorServer
import com.xixilala.video.util.FileUtil
import com.xixilala.video.util.FileUtil.mp4Assets2CachePath
import java.nio.ByteBuffer

/**
 * MediaExtractor 和 MediaMuxer API，知道如何解析和封装 mp4 文件
 */
class Practice4Fragment : BaseFragment() {

    private lateinit var mBinding: FragmentPractice4Binding

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
        mBinding = FragmentPractice4Binding.inflate(inflater, container, false)
        return mBinding.root
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)

        ExecutorServer.submit {
            mp4Assets2CachePath(App.appContext)
        }

        mBinding.run {
            btnParseMp4.setOnClickListener {
                ExecutorServer.submit {parseMp4()}
            }

            btnPlayMp4.setOnClickListener {
                //TODO 手机录的视频方向不对
                vvResult.setVideoPath(FileUtil.getTestOutputVideo(App.appContext).absolutePath)
                vvResult.start()
            }
        }

    }

    private fun parseMp4() {
        val mediaExtractorVideo = MediaExtractor()
        val mediaExtractorAudio = MediaExtractor()
        val muxerVideo = MediaMuxer(FileUtil.getTestOutputVideo(App.appContext).absolutePath, MediaMuxer.OutputFormat.MUXER_OUTPUT_MPEG_4)

        var videoIndex = -1
        var audioIndex = -1
        var maxInputSize = 1024
        mediaExtractorVideo.setDataSource(FileUtil.getTestMp4(App.appContext).absolutePath)
        mediaExtractorAudio.setDataSource(FileUtil.getTestMp4(App.appContext).absolutePath)
        val trackCount = mediaExtractorVideo.trackCount // 获取轨道数量，音轨，视频轨
        val buffer = StringBuffer()
        buffer.append("编号通道数量:$trackCount").append("\n")
        for(i in 0 until trackCount) {
            val trackFormat = mediaExtractorVideo.getTrackFormat(i)
            val mine = trackFormat.getString(MediaFormat.KEY_MIME)
            buffer.append(" 编号 $i 通道格式：${mine}").append("\n")
            mine?.let {
                if (mine.startsWith("video/")) {
                    videoIndex = i
                    val width        = trackFormat.getInteger(MediaFormat.KEY_WIDTH)
                    val height       = trackFormat.getInteger(MediaFormat.KEY_HEIGHT)
                    val duration     = trackFormat.getLong(MediaFormat.KEY_DURATION)
                    //视频缓存输出的最大大小
                    maxInputSize = trackFormat.getInteger(MediaFormat.KEY_MAX_INPUT_SIZE)
                    buffer.append("video width=$width height=$height duration=$duration maxInputSize=$$maxInputSize").append("\n")

                    mediaExtractorVideo.selectTrack(i)//选到视频轨
                    videoIndex = muxerVideo.addTrack(trackFormat)
                }
                if (mine.startsWith("audio/")) {
                    mediaExtractorAudio.selectTrack(i)
                    audioIndex = muxerVideo.addTrack(trackFormat)
                }
            }
        }

        mBinding.btnParseMp4.post {
            mBinding.tvParseResult.text = buffer.toString()
        }

        muxerVideo.start()

        val bufferInfo = MediaCodec.BufferInfo()
        val bufferInfo1 = MediaCodec.BufferInfo()
        bufferInfo.presentationTimeUs = 0
        bufferInfo1.presentationTimeUs = 0
        val byteBuffer = ByteBuffer.allocate(maxInputSize) //取 KEY_MAX_INPUT_SIZE
        while (true) {
            val readSampleData = mediaExtractorVideo.readSampleData(byteBuffer, 0)
            if (readSampleData < 0) {
                break
            }
            bufferInfo.offset = 0
            bufferInfo.size = readSampleData
            bufferInfo.flags = MediaCodec.BUFFER_FLAG_KEY_FRAME
            bufferInfo.presentationTimeUs = mediaExtractorVideo.sampleTime
            muxerVideo.writeSampleData(videoIndex,byteBuffer,bufferInfo)

            mediaExtractorVideo.advance()
        }


        while (true) {
            val readSampleData = mediaExtractorAudio.readSampleData(byteBuffer, 0)
            if (readSampleData < 0) {
                break
            }
            bufferInfo1.offset = 0
            bufferInfo1.size = readSampleData
            bufferInfo1.flags = MediaCodec.BUFFER_FLAG_KEY_FRAME
            bufferInfo1.presentationTimeUs = mediaExtractorAudio.sampleTime
            muxerVideo.writeSampleData(audioIndex,byteBuffer,bufferInfo1)

            mediaExtractorAudio.advance()
        }

        buffer.append("\n解析完毕，可以播放")
        mBinding.btnParseMp4.post {
            mBinding.tvParseResult.text = buffer.toString()
        }

        mediaExtractorVideo.release()
        mediaExtractorAudio.release()
        muxerVideo.stop()
        muxerVideo.release()


    }
}